
/*******************************************************************************
 * Copyleft (c) 2021 Kcode
 *
 * @file    main.c
 * @brief   ALSA裸板程序的主函数文件
 * @author  K
 * @version 0.0.1
 * @date    2021-08-05
 * @license MulanPSL-1.0
 *
 * 文件修改历史：
 * <时间>       | <版本>    | <作者>  | <描述>
 * 2021-08-05   | v0.0.1    | Kcode   | ALSA裸板程序的主函数文件
 * -----------------------------------------------------------------------------
 ******************************************************************************/

#include <stdio.h>
#include "serial.h"

void init_irq(void);
void read_wav(unsigned int wav_buf, int *fs, int *channels, int *bits_per_sample, int *wav_size);
void iis_init(int bits_per_sample, int fs);
void iis_start(void);
void iis_stop(void);
void dma_init(unsigned int src, unsigned int len);
void dma_start(void);
void dma_stop(void);
void jz2440_init(void);
void tq2440_init(void);
void mini2440_init(void);
void wm8976_init(void);
void wm8976_set_volume(int volume);
void uda1341_init(void);
void uda1341_set_volume(int volume);

void delay()
{
    volatile int i = 1000;
    while(i--);
}

int main()
{
    char c;                 /**< 标准输入得到的字符 */
    int volume = 50;        /**< 音量：0~100 */
    unsigned int wav_buf;   /**< 存储读出的wav文件数据的地址 */
    int fs;                 /**< 采样率*/
    int channels;           /**< 通道数*/
    int bits_per_sample;    /**< 每个采样值占据位数*/
    int wav_size;           /**< wav文件中总数据的大小*/

    void (*set_volume)(int);
    
    wav_buf = 0x30000000;
    
    /*!
     * 串口初始化：波特率115200，8N1(8个数据位，无校验位，1个停止位)
     */
    uart0_init();

    /*!
     * 初始化中断
     */
    init_irq();

    /*!
     * 读取wav文件，从NAND中把wav文件读到SDRAM
     * 获得wav文件的格式：通道数，采样率等
     */
    read_wav(wav_buf, &fs, &channels, &bits_per_sample, &wav_size);
    printf("wav_format : fs = %d, channels = %d, bits_per_sample = %d, wav_size = %d", 
                    fs, channels, bits_per_sample, wav_size);
    if (channels != 2 || (bits_per_sample != 8 && bits_per_sample != 16))
    {
        printf("can not support\n");
        while(1);
    }
    
    /*!
     * 进行视频播放
     */
    while (1)
    {
        /*!
         * 初始化视频数据传输的iis与dma传输
         * 初始化iis后才会给codec芯片发送时钟，使其能被使用
         */
menu:   
        iis_init(bits_per_sample, fs);
        dma_init(wav_buf, wav_size);
             
        printf("\r\n##### Sound Menu #####\r\n");
        printf("[J] JZ2440\n\r");
        printf("[M] MINI2440\n\r");
        printf("[T] TQ2440\n\r");
        printf("Enter your selection: ");

        c = getc();
        printf("%c\n\r", c);

        /*!
         * 根据不同的裸板进行对应的裸板初始化
         */
        switch (c)
        {
            case 'J':
            case 'j':
            {
                /* machine init */
                jz2440_init();
                
                /* codec init */
                wm8976_init();
                set_volume = wm8976_set_volume;
                break;
            }
            
            case 'm':
            case 'M':
            {
                /* machine init */
                mini2440_init();

                /* codec init */
                uda1341_init();
                set_volume = uda1341_set_volume;
                break;
            }

            case 't':
            case 'T':
            {
                /* machine init */
                tq2440_init();

                /* codec init */
                uda1341_init();
                set_volume = uda1341_set_volume;
                break;
            }

            default:
            {
                goto menu;
            }
        }        

        /*!
         * 设置默认音量
         */
        set_volume(volume);
        
        /*!
         * 开始视频数据传输(视频播放)
         */
        dma_start();
        iis_start();

        /*!
         * 调整音量
         */
        printf("\r\n##### Operate Menu #####\r\n");
        printf("[-] volume down\n\r");
        printf("[+] volume up\n\r");
        printf("[Q] Quit\n\r");
        printf("Cur volume: %03d", volume);
        while (1)
        {
            c = getc();
            if (c == 'q' || c == 'Q')
            {
                printf("%c\n\r", c);
                iis_stop();
                dma_stop();
                break;
            }
            else if (c == '-')
            {
                if (volume > 0)
                    volume--;
                set_volume(volume);
            }
            else if (c == '+')
            {
                if (volume < 100)
                    volume++;
                set_volume(volume);
            }
            printf("\b\b\b%03d", volume);
        }    
    }
    
    return 0;
}
